package main

import (
	"crypto/md5"
	"encoding/hex"
	"math/rand"
	"os"
	"sync"
	"time"
)

var (
	objIdMutex sync.Mutex
	pid        = int32(os.Getpid())
	machine    = getMachineHash()
	increment  = getRandomNumber()
)

func NextObjectId() string {
	objIdMutex.Lock()
	defer objIdMutex.Unlock()
	timestamp := time.Now().Unix()
	increment++
	array := []byte{
		byte(timestamp >> 0x18),
		byte(timestamp >> 0x10),
		byte(timestamp >> 8),
		byte(timestamp),
		byte(machine >> 0x10),
		byte(machine >> 8),
		byte(machine),
		byte(pid >> 8),
		byte(pid),
		byte(increment >> 0x10),
		byte(increment >> 8),
		byte(increment),
	}
	return hex.EncodeToString(array)
}

func getMachineHash() int32 {
	machineName, err := os.Hostname()
	if err != nil {
		panic(err)
	}
	buf := md5.Sum([]byte(machineName))
	return (int32(buf[0])<<0x10 + int32(buf[1])<<8) + int32(buf[2])
}

func getRandomNumber() int32 {
	rand.Seed(time.Now().UnixNano())
	return rand.Int31()
}
